Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow WebUser invites to be editable before the invited user accepts it #35538

Merged
merged 14 commits into from
Dec 19, 2024

Conversation

minhaminha
Copy link
Contributor

@minhaminha minhaminha commented Dec 18, 2024

Product Description

Users will now have the ability to edit web user invites before the invited user has accepted it. They'll be able to change any field that was visible to them when initially making the invitation (except the email field - if a user wants to change who the invite is for, they will have to delete the existing invite and create a new one). This edit page will be accessible through a new 'Edit' button that'll appear next to every pending invite.

Screen Shot 2024-12-11 at 1 22 04 PM

When entering the form, the user will see that they are now in the 'Edit Web User Invite' page on the sidebar menu and the submit button will show 'Update Invite'. Editing the invite will not send a new invite email.

This change is compatible with the web_user_invite_additional_fields feature flag, which adds additional user defined fields to the invite form.

Technical Summary

Jira Ticket

This new edit form reuses the original create form but checks first to see if an invitation id is in the request. If there is one, it'll pre-populate the form with previously submitted input wherever is applicable.

Feature Flag

Doesn't strictly use it but is compatible with web_user_invite_additional_fields.

Safety Assurance

Safety story

Tested locally and on staging. The blast radius is limited to the user/invitation creation operations, including mobile worker creation and domain requests (both areas I've asked QA to cover).

QA Plan

QA ticket

Rollback instructions

  • This PR can be reverted after deploy with no further considerations

Labels & Review

  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@minhaminha minhaminha added QA Passed product/all-users-all-environments Change impacts all users on all environments labels Dec 18, 2024
@minhaminha minhaminha requested a review from esoergel as a code owner December 18, 2024 19:42
@dimagimon dimagimon added the Risk: High Change affects files that have been flagged as high risk. label Dec 18, 2024
@minhaminha minhaminha added awaiting QA QA in progress. Do not merge and removed QA Passed labels Dec 18, 2024
Copy link
Contributor

@esoergel esoergel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't able to do a super thorough review, but it looks good save for a couple nitpicks


self.helper = FormHelper()
self.helper.form_method = 'POST'
self.helper.form_class = 'form-horizontal form-ko-validation'

self.helper.label_class = 'col-sm-3 col-md-2'
self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'

save_button_text = "Send Invite"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and the alternate text should be marked for translation

@@ -575,8 +584,7 @@ def __init__(self, data=None, is_add_user=None,
),
hqcrispy.FormActions(
twbscrispy.StrictButton(
(gettext("Add User") if is_add_user
else gettext("Send Invite")),
(gettext("Add User") if is_add_user else gettext(save_button_text)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passing a variable to gettext will only translate that var if it's already marked for translation elsewhere, such as with gettext_noop. Probably most straightforward to just move the gettext call to where those strings are defined in this case.

Comment on lines 1163 to 1164
if invitation and invitation.email in pending_invites:
pending_invites.remove(invitation.email)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow, what's going on here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The invite form will normally throw an error if you try to send an invite to an email that has an invite pending/already belongs to the domain. Since the edit form reuses that same form, I need to take out the email belonging to the invite that's being edited so it can submit/save properly.

@@ -1144,7 +1144,9 @@ def invite_web_user_form(self):
if invitation:
assigned_location = invitation.assigned_locations.filter()
assigned_location_ids = [loc.location_id for loc in assigned_location]
primary_location_id = invitation.primary_location.location_id
primary_location_id = None
if assigned_location_ids:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this check primary_location instead of assigned_location_ids? It should work the same in either case, just seems clearer

corehq/apps/users/static/users/js/custom_data_fields.js Outdated Show resolved Hide resolved
corehq/apps/registration/forms.py Outdated Show resolved Hide resolved
corehq/apps/users/static/users/js/web_users.js Outdated Show resolved Hide resolved
corehq/apps/users/views/__init__.py Outdated Show resolved Hide resolved
corehq/apps/users/views/__init__.py Outdated Show resolved Hide resolved
corehq/apps/users/views/__init__.py Outdated Show resolved Hide resolved
corehq/apps/users/views/__init__.py Show resolved Hide resolved
corehq/apps/users/views/__init__.py Outdated Show resolved Hide resolved
corehq/apps/registration/forms.py Show resolved Hide resolved
@minhaminha minhaminha added QA Passed and removed awaiting QA QA in progress. Do not merge labels Dec 19, 2024
@Jtang-1
Copy link
Contributor

Jtang-1 commented Dec 19, 2024

nit: I noticed this line shows up when you hover the edit button.
I think it's because on hover over an a tag, it adds an underline text-decoration
Screenshot

corehq/apps/registration/forms.py Show resolved Hide resolved
corehq/apps/registration/forms.py Outdated Show resolved Hide resolved
@minhaminha minhaminha requested a review from esoergel December 19, 2024 20:04
@minhaminha minhaminha requested a review from Jtang-1 December 19, 2024 20:04
Copy link
Contributor

@Jtang-1 Jtang-1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, good work on this! And thank you for responding to my million comments

@@ -594,7 +606,7 @@ def clean_email(self):
email = self.cleaned_data['email'].strip()

from corehq.apps.registration.validation import AdminInvitesUserFormValidator
error = AdminInvitesUserFormValidator.validate_email(self.domain, email)
error = AdminInvitesUserFormValidator.validate_email(self.domain, email, bool(self.invite))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to skip all this validation if the field is set as read only? And then add a validation that the email didn't change like

    if self.fields['email'].widget.attrs.get('readonly', False):
        if email != self.invite.email:
            raise forms.ValidationError("The email field is read-only and cannot be changed.")
            ```

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what I have currently is simpler

@minhaminha minhaminha merged commit 6a10621 into master Dec 19, 2024
13 checks passed
@minhaminha minhaminha deleted the ml/editable-webuser-invite branch December 19, 2024 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
product/all-users-all-environments Change impacts all users on all environments QA Passed Risk: High Change affects files that have been flagged as high risk.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants